package com.openlogic.common.rabbitmq.config;

import java.util.Map;
import java.util.Optional;

import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.openlogic.common.rabbitmq.config.properties.RabbitProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @ClassName: RabbitMQAutoConfiguration
 * @Description: Rabbitmq消息队列自动注入配置类
 * @author weiyongpeng
 * @date 2024年12月24日 下午4:54:14
 */
@Configuration
public class RabbitMQAutoConfiguration {

	private static final Logger log = LoggerFactory.getLogger(RabbitMQAutoConfiguration.class);

	@Inject
	private RabbitProperties rabbitProperties;
	
	private Channel channel;

//	@Bean
//	public RabbitService rabbitService() {
//		return new RabbitServiceImpl();
//	}

//    @Bean
//    public void rabbitMQConnectionFactory() {
//        Optional.ofNullable(rabbitProperties).map(RabbitProperties::getExchangeInfos).filter(CollUtil::isNotEmpty).ifPresent(list -> {
//            // 创建连接工厂
//            ConnectionFactory factory = new ConnectionFactory();
//            list.forEach(item -> {
//                try {
//                    String host = StrUtil.isNotBlank(item.getHost()) ? item.getHost() : rabbitProperties.getHost();
//                    Integer port = ObjectUtil.isNotNull(item.getPort()) ? item.getPort() : rabbitProperties.getPort();
//                    String username = StrUtil.isNotBlank(item.getUsername()) ? item.getUsername() : rabbitProperties.getUsername();
//                    String password = StrUtil.isNotBlank(item.getPassword()) ? item.getPassword() : rabbitProperties.getPassword();
//                    if (StrUtil.isBlank(host)) {
//                        throw new UtilException("地址（host）为空");
//                    } else if (StrUtil.isBlank(item.getType())) {
//                        throw new UtilException("交换机类型（type）为空");
//                    } else if (StrUtil.isBlank(item.getName())) {
//                        throw new UtilException("交换机名称（name）为空");
//                    }
//                    String evnName = rabbitProperties.getEvnPrefix();
//                    // 设置RabbitMQ服务器信息
//                    factory.setHost(host);
//                    factory.setPort(port);
//                    factory.setUsername(username);
//                    factory.setPassword(password);
//                    // 创建一个新的连接 创建一个通道
//                    try(Connection connection = factory.newConnection();
//                    	Channel channel= connection.createChannel();) 
//                    {
//                        // 声明一个Exchange
//                        String exchangeName = StrUtil.format("{}{}", evnName, item.getName());
//                        Map<String, Object> exchangeArguments = MapUtil.isNotEmpty(item.getParams()) ? item.getParams() : null;
//                        channel.exchangeDeclare(exchangeName, item.getType(), item.getDurable(), item.getAutoDelete(), item.getExclusive(), exchangeArguments);
//                        Optional.ofNullable(item.getQueueInfos()).filter(CollUtil::isNotEmpty).ifPresent(queueInfos -> queueInfos.forEach(queueInfo -> {
//                            try {
//                                // 声明一个Queue
//                                String queueName = StrUtil.format("{}{}", evnName, queueInfo.getName());
//                                Map<String, Object> arguments = MapUtil.isNotEmpty(queueInfo.getParams()) ? queueInfo.getParams() : null;
//                                channel.queueDeclare(queueName, queueInfo.getDurable(), queueInfo.getExclusive(), queueInfo.getAutoDelete(), arguments);
//                                // 将Queue绑定到Exchange
//                                String routingKeyName = StrUtil.format("{}{}", evnName, queueInfo.getRoutingKey());
//                                channel.queueBind(queueName, exchangeName, routingKeyName);
//                            } catch (Exception e) {
//                                log.error("RabbitMQ连接创建失败，原因：{}\n", e.getMessage(), e);
//                            }
//                        }));
//                    }
//                } catch (Exception e) {
//                    log.error("RabbitMQ连接创建失败，原因：{}\n", e.getMessage(), e);
//                }
//            });
//        });
//    }
	
	@Bean(index = 5)
    public ConnectionFactory rabbitMQConnectionFactory() {
		ConnectionFactory factory = new ConnectionFactory();
        Optional.ofNullable(rabbitProperties).map(RabbitProperties::getExchangeInfos).filter(CollUtil::isNotEmpty).ifPresent(list -> {
            // 创建连接工厂
            list.forEach(item -> {
                try {
                    String host = StrUtil.isNotBlank(item.getHost()) ? item.getHost() : rabbitProperties.getHost();
                    Integer port = ObjectUtil.isNotNull(item.getPort()) ? item.getPort() : rabbitProperties.getPort();
                    String username = StrUtil.isNotBlank(item.getUsername()) ? item.getUsername() : rabbitProperties.getUsername();
                    String password = StrUtil.isNotBlank(item.getPassword()) ? item.getPassword() : rabbitProperties.getPassword();
                    if (StrUtil.isBlank(host)) {
                        throw new UtilException("地址（host）为空");
                    } else if (StrUtil.isBlank(item.getType())) {
                        throw new UtilException("交换机类型（type）为空");
                    } else if (StrUtil.isBlank(item.getName())) {
                        throw new UtilException("交换机名称（name）为空");
                    }
                    // 设置RabbitMQ服务器信息
                    factory.setHost(host);
                    factory.setPort(port);
                    factory.setUsername(username);
                    factory.setPassword(password);
                } catch (Exception e) {
                    log.error("RabbitMQ连接创建失败，原因：{}\n", e.getMessage(), e);
                }
            });
        });
        return factory;
    }
	
	@Bean
    public Channel rabbitMQConnectionFactory(@Inject ConnectionFactory factory) {
        Optional.ofNullable(rabbitProperties).map(RabbitProperties::getExchangeInfos).filter(CollUtil::isNotEmpty).ifPresent(list -> {
            // 创建连接工厂
            list.forEach(item -> {
                try {
                    String evnName = rabbitProperties.getEvnPrefix();
                    // 创建一个新的连接 创建一个通道
                    try(Connection connection = factory.newConnection();) 
                    {
                    	channel = connection.createChannel();
                        // 声明一个Exchange
                        String exchangeName = StrUtil.format("{}{}", evnName, item.getName());
                        Map<String, Object> exchangeArguments = MapUtil.isNotEmpty(item.getParams()) ? item.getParams() : null;
                        channel.exchangeDeclare(exchangeName, item.getType(), item.getDurable(), item.getAutoDelete(), item.getExclusive(), exchangeArguments);
                        Optional.ofNullable(item.getQueueInfos()).filter(CollUtil::isNotEmpty).ifPresent(queueInfos -> queueInfos.forEach(queueInfo -> {
                            try {
                                // 声明一个Queue
                                String queueName = StrUtil.format("{}{}", evnName, queueInfo.getName());
                                Map<String, Object> arguments = MapUtil.isNotEmpty(queueInfo.getParams()) ? queueInfo.getParams() : null;
                                channel.queueDeclare(queueName, queueInfo.getDurable(), queueInfo.getExclusive(), queueInfo.getAutoDelete(), arguments);
                                // 将Queue绑定到Exchange
                                String routingKeyName = StrUtil.format("{}{}", evnName, queueInfo.getRoutingKey());
                                channel.queueBind(queueName, exchangeName, routingKeyName);
                            } catch (Exception e) {
                                log.error("RabbitMQ连接创建失败，原因：{}\n", e.getMessage(), e);
                            }
                        }));
                    }
                } catch (Exception e) {
                    log.error("RabbitMQ连接创建失败，原因：{}\n", e.getMessage(), e);
                }
            });
        });
        return channel;
    }

	/**
	 * 消息序列化消息
	 */
//	@Bean
//	public MessageConverter createMessageConverter() {
//		return new Jackson2JsonMessageConverter();
//	}

}
